package com.own.core.html.component.link;

import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.IAjaxCallDecorator;
import org.apache.wicket.ajax.calldecorator.CancelEventIfNoAjaxDecorator;
import org.apache.wicket.ajax.markup.html.IAjaxLink;
import org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel;
import org.apache.wicket.extensions.breadcrumb.IBreadCrumbParticipant;
import org.apache.wicket.extensions.breadcrumb.panel.BreadCrumbPanel;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.link.Link;

import com.own.core.html.component.OwnBreadCrumbPanelFactory;
 
public abstract class OwnBreadCrumbAjaxLink extends Link  implements IAjaxLink{

	private static final long serialVersionUID = 1L;

	 
	private   IBreadCrumbModel breadCrumbModel;

 

	/**
	 * @see org.apache.wicket.markup.html.link.Link#onClick()
	 */
 
 

	/** factory for creating bread crumbs panels. */
	private final OwnBreadCrumbPanelFactory breadCrumbPanelFactory;

	/**
	 * Construct.
	 * 
	 * @param id
	 *            The component id
	 * @param caller
	 *            The calling panel which will be used to get the {@link IBreadCrumbModel bread
	 *            crumb model} from.
	 * @param panelClass
	 *            The class to use for creating instances. Must be of type {@link BreadCrumbPanel},
	 *            and must have constructor
	 *            {@link BreadCrumbPanel#BreadCrumbPanel(String, IBreadCrumbModel)}
	 */
	public OwnBreadCrumbAjaxLink(final String id, final BreadCrumbPanel caller,
		final Class panelClass)
	{
		this(id, caller.getBreadCrumbModel(), new OwnBreadCrumbPanelFactory(panelClass));
	}

	/**
	 * Construct.
	 * 
	 * @param id
	 *            The component id
	 * @param breadCrumbModel
	 *            The bread crumb model
	 * @param panelClass
	 *            The class to use for creating instances. Must be of type {@link BreadCrumbPanel},
	 *            and must have constructor
	 *            {@link BreadCrumbPanel#BreadCrumbPanel(String, IBreadCrumbModel)}
	 */
	public OwnBreadCrumbAjaxLink(final String id, final IBreadCrumbModel breadCrumbModel,
		final Class panelClass)
	{
		this(id, breadCrumbModel, new OwnBreadCrumbPanelFactory(panelClass));
	}

	/**
	 * Construct.
	 * 
	 * @param id
	 *            The component id
	 * @param breadCrumbModel
	 *            The bread crumb model
	 * @param breadCrumbPanelFactory
	 *            The factory to create bread crumb panels
	 */
	public OwnBreadCrumbAjaxLink(final String id, final IBreadCrumbModel breadCrumbModel,
		final OwnBreadCrumbPanelFactory breadCrumbPanelFactory)
	{
		super(id);
		this.breadCrumbModel = breadCrumbModel;
		if (breadCrumbModel == null)
		{
			throw new IllegalArgumentException("argument breadCrumbModel must be not null");
		}
		if (breadCrumbPanelFactory == null)
		{
			throw new IllegalArgumentException("argument breadCrumbPanelFactory must be not null");
		}

		this.breadCrumbModel = breadCrumbModel;
		this.breadCrumbPanelFactory = breadCrumbPanelFactory;
		
		
		
		add(new AjaxEventBehavior("onclick")
		{
			private static final long serialVersionUID = 1L;

			/**
			 * 
			 * @see org.apache.wicket.ajax.AjaxEventBehavior#onEvent(org.apache.wicket.ajax.AjaxRequestTarget)
			 */
			@Override
			protected void onEvent(AjaxRequestTarget target)
			{
				
				// get the currently active particpant
				final IBreadCrumbParticipant active = breadCrumbModel.getActive();
				if (active == null)
				{
					throw new IllegalStateException("The model has no active bread crumb. Before using " +
						this + ", you have to have at least one bread crumb in the model");
				}

				// get the participant to set as active
				final IBreadCrumbParticipant participant = getParticipant(active.getComponent().getId());

				// add back button support
				addStateChange();

				// set the next participant as the active one
				breadCrumbModel.setActive(participant);
				onClick(target);
			}

			/**
			 * 
			 * @see org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#getAjaxCallDecorator()
			 */
			@Override
			protected IAjaxCallDecorator getAjaxCallDecorator()
			{
				return new CancelEventIfNoAjaxDecorator(
						OwnBreadCrumbAjaxLink.this.getAjaxCallDecorator());
			}

			/**
			 * 
			 * @see org.apache.wicket.ajax.AjaxEventBehavior#onComponentTag(org.apache.wicket.markup.ComponentTag)
			 */
			@Override
			protected void onComponentTag(ComponentTag tag)
			{
				// only render handler if link is enabled
				if (isLinkEnabled())
				{
					super.onComponentTag(tag);
				}
			}
		});
		
		
	}

	/**
	 * Uses the set factory for creating a new instance of {@link IBreadCrumbParticipant}.
	 * 
	 * @see org.apache.wicket.extensions.breadcrumb.BreadCrumbLink#getParticipant(java.lang.String)
	 */
 
	protected final IBreadCrumbParticipant getParticipant(String componentId)
	{
		return breadCrumbPanelFactory.create(componentId, breadCrumbModel);
	}
	
	/**
	 * 
	 * @return call decorator to use or null if none
	 */
	protected IAjaxCallDecorator getAjaxCallDecorator()
	{
		return null;
	}

	/**
	 * 
	 * @see org.apache.wicket.markup.html.link.Link#onClick()
	 */
	@Override
	public final void onClick()
	{
		onClick(null);
	}
	/**
	 * Callback for the onClick event. If ajax failed and this event was generated via a normal link
	 * the target argument will be null
	 * 
	 * @param target
	 *            ajax target if this linked was invoked using ajax, null otherwise
	 */
	public abstract void onClick(final AjaxRequestTarget target);
}